package cn.shenlong.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.time.DateFormatUtils;

/**
 * @author shenlong
 * 
 */
public class XlsUtil {

	/**
	 * 创建excel文件
	 * 
	 * @param exportData
	 *            写入excel的数据
	 * @param rowMapper
	 *            excel标题，key必须与List bean 中的属性名一致
	 * @param outputPath
	 *            完整路径
	 * @return
	 */
	public static File createXlsFile(List exportData, LinkedHashMap rowMapper,
			String outputPath) {
		OutputStream out = null;
		WritableWorkbook writebook = null;
		try {
			out = new FileOutputStream(outputPath);
			writebook = Workbook.createWorkbook(out);
			WritableSheet sheet = writebook.createSheet("sheet1", 0);

			// 写入文件头部
			int cols = 0;
			for (Iterator propertyIterator = rowMapper.entrySet().iterator(); propertyIterator
					.hasNext();) {
				java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator
						.next();
				sheet.addCell(new Label(cols, 0, propertyEntry.getValue()
						.toString()));
				cols++;
			}

			// 写入文件内容
			int rows = 1;
			cols = 0;
			for (Iterator iterator = exportData.iterator(); iterator.hasNext();) {
				Object row = (Object) iterator.next();
				for (Iterator propertyIterator = rowMapper.entrySet()
						.iterator(); propertyIterator.hasNext();) {
					java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator
							.next();
					String val = null;
					Object valObj = PropertyUtils.getProperty(row,
							propertyEntry.getKey().toString());
					if (valObj instanceof java.util.Date) {
						val = DateFormatUtils.format((java.util.Date) valObj,
								"yyyy-MM-dd");
					} else {
						val = BeanUtils.getProperty(row, propertyEntry.getKey()
								.toString());
					}
					val = val == null ? "" : val;
					sheet.addCell(new Label(cols, rows, val));
					if (propertyIterator.hasNext()) {
						cols++;
					}
				}
				if (iterator.hasNext()) {
					cols = 0;
					rows++;
				}
			}
			writebook.write();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				writebook.close();
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return new File(outputPath);
	}

	public static void exportToXlsFile(HttpServletResponse response,
			List exportData, LinkedHashMap rowMapper, String fileName,
			String outputPath) throws FileNotFoundException {
		File xlsFile = createXlsFile(exportData, rowMapper, outputPath);
		downFile(response, fileName, new FileInputStream(xlsFile));
		xlsFile.delete();
	}

	private static void downFile(HttpServletResponse response, String fileName,
			FileInputStream fileInputStream) {
		response.setContentType("application/xls");
		try {
			response.setHeader("Content-Disposition", "attachment; filename=\""
					+ new String(fileName.getBytes("gb2312"), "ISO8859-1")
					+ "\"");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		response.setStatus(HttpServletResponse.SC_OK);
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int ch;
			while ((ch = fileInputStream.read()) != -1) {
				baos.write(ch);
			}
			byte data[] = baos.toByteArray();
			out.write(data);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
